package org.cn.osiris.basic.interceptor;

import io.jsonwebtoken.ExpiredJwtException;
import org.cn.osiris.basic.jwt.JwtUtils;
import org.cn.osiris.basic.jwt.LoginData;
import org.cn.osiris.basic.jwt.Payload;
import org.cn.osiris.basic.jwt.RsaUtils;
import org.cn.osiris.org.mapper.EmployeeMapper;
import org.cn.osiris.system.annotation.PreAuthorize;
import org.cn.osiris.user.domain.Logininfo;
import org.omg.PortableInterceptor.Interceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Component//交给IOC管理
public class LoginInterceptor implements HandlerInterceptor {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private EmployeeMapper employeeMapper;

    /**
     *请求到达处理器之前执行
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //获取token
        String token = request.getHeader("token");
        //如果存在token 通过token获得redis的登录信息
        if (token != null){
            Logininfo info = null;
            try {
                //获取公钥
                PublicKey publicKey = RsaUtils.getPublicKey(LoginInterceptor.class.getClassLoader().getResource("auth_rsa.pub").getFile());
                //解密
                Payload<LoginData> payload = JwtUtils.getInfoFromToken(token, publicKey, LoginData.class);
                //获取info
                info = payload.getLoginData().getLogininfo();
            } catch (ExpiredJwtException e) {
                e.printStackTrace();
                //不包含 --拦截 给axios的后置拦截器一个响应
                response.setContentType("application/json;charset=UTF-8");
                response.getWriter().println("{\"success\":false,\"message\":\"timeOut\"}");
                return false;
            }

            if (info.getType()==1){
                    //用户 ---直接放行
                    //管理员 ---校验该管理员的拥有权限
                    return true;
                }
                //2、获取当前登录人的所有权限
                List<String> sns = employeeMapper.getSns(info.getId());

                HandlerMethod method = (HandlerMethod) handler;
                //获取当前访问接口的名称
                System.out.println(method.getMethod().getName());
                //3、获取当前访问的接口上的自定义注解
                    //校验是否有注解  如果有，获取sn属性值
                    //如果包含sn --放行
                PreAuthorize preAuthorize = method.getMethodAnnotation(PreAuthorize.class);
                System.out.println(preAuthorize);
                //如果为null直接放行
                if (preAuthorize==null){
                    return true;
                }
                //获取注解的值
                String sn = preAuthorize.sn();
                if (sns.contains(sn)){
                    return true;
                }


                //不包含 --拦截 给axios的后置拦截器一个响应
                response.setContentType("application/json;charset=UTF-8");
                response.getWriter().println("{\"success\":false,\"message\":\"noPermission\"}");
                return false;

        }
        //判断token的结果为null，说明当前未进行登录，直接拦截该请求，并且跳转到登录页面，进行重新登录
        //如果登录信息为null 说明登录时间过期 拦截该请求，并且跳转到登录页面，进行重新登录

        //因为是前后端分离项目 我们的页面跳转是在前端实现
        //将我们放行的请求告诉浏览器响应一个json数据

        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().println("{\"success\":false,\"message\":\"noLogin\"}");
        return false;
    }


}
